using System;
using System.Collections.Generic;
using Mbs.Collections;

namespace Mbs.Messaging.Imp
{

    [Serializable]
    public class SubjectBuilder : MarshalByRefObject, ISubjectBuilder
    {
        class MessageQueue<T> : Queue<T>, IQueue<T>
        {
            private readonly object synRoot = new object();
            public object SyncRoot { get { return synRoot; } }
            public bool IsSynchronized { get { return false; } }

            public void Dispose()
            {
                Clear();
            }
        }

        public virtual ISubject<T> Build<T>(string name)
        {
            var subject = CreateSubject<T>(name);

            subject.Queue = CreateQueue<KeyValuePair<object, T>>();
            subject.Subscriber = CreateSubscriber<T>();
            subject.Executor = CreateExecutor<T>();

            subject.Subscriber.Name = subject.Name;
            subject.Executor.Subject = subject;

            return subject;
        }

        protected virtual ISubject<T> CreateSubject<T>(string name)
        {
            return new Subject<T>(name);
        }

        protected virtual IQueue<T> CreateQueue<T>()
        {
            return new MessageQueue<T>();
        }

        protected virtual ISubscriber<T> CreateSubscriber<T>()
        {
            return new Subscriber<T>();
        }

        protected virtual IExecutor<T> CreateExecutor<T>()
        {
            return new Executor<T>();
        }
    }
}
